/******************************************************************************
秋夜静，独坐对残灯。
啼笑非非谁识我，坐行梦梦尽缘君，何所慰消沉。
风卷雨，雨复卷侬心。
心似欲随风雨去，茫茫大海任浮沉。
无爱亦无恨。
******************************************************************************/
#include "kbRGB_Angle.h"
#include <stdio.h>
#include <math.h>

static const uint16_t RotateMatrixAngle[KBRGB_ANGLE_SIZE][KBRGB_ANGLE_SIZE] = {
{0x0000, 0x0800, 0x1000, 0x1800, 0x2000, 0x2800, 0x3000, 0x3800, 0x4000, 0x4800, 0x5000, 0x5800, 0x6000, 0x6800, 0x7000, 0x7800, 0x8000, 0x8800, 0x9000, 0x9800, 0xA000, },
{0x0ACF, 0x0967, 0x10D4, 0x1893, 0x2070, 0x285A, 0x304B, 0x3841, 0x4039, 0x4832, 0x502D, 0x5829, 0x6026, 0x6823, 0x7020, 0x781E, 0x801C, 0x881A, 0x9019, 0x9818, 0xA016, },
{0x12CF, 0x11FB, 0x1567, 0x1D0D, 0x20D4, 0x28AE, 0x3093, 0x387F, 0x4070, 0x4864, 0x505A, 0x5852, 0x604B, 0x6845, 0x7041, 0x783C, 0x8039, 0x8835, 0x9032, 0x9830, 0xA02D, },
{0x1ACF, 0x1A3C, 0x1DC2, 0x2167, 0x2926, 0x2CF7, 0x34D4, 0x3CB9, 0x44A4, 0x4893, 0x5085, 0x587A, 0x6070, 0x6867, 0x7060, 0x785A, 0x8054, 0x8850, 0x904B, 0x9847, 0xA044, },
{0x22CF, 0x225F, 0x21FB, 0x29A9, 0x2D67, 0x3135, 0x390D, 0x40ED, 0x44D4, 0x4CBF, 0x54AE, 0x5C9F, 0x6493, 0x6C88, 0x747F, 0x7C77, 0x8070, 0x8869, 0x9064, 0x985F, 0xA05A, },
{0x2ACF, 0x2A75, 0x2A21, 0x2DD8, 0x319A, 0x3967, 0x3D3E, 0x451C, 0x4900, 0x50E8, 0x58D4, 0x60C3, 0x68B4, 0x6CA8, 0x749D, 0x7C93, 0x848A, 0x8C83, 0x947C, 0x9C75, 0xA470, },
{0x32CF, 0x3284, 0x323C, 0x35FB, 0x39C2, 0x3D91, 0x4167, 0x4944, 0x5126, 0x550D, 0x5CF7, 0x64E4, 0x68D4, 0x70C6, 0x78B9, 0x80AE, 0x88A4, 0x909B, 0x9493, 0x9C8C, 0xA485, },
{0x3ACF, 0x3A8E, 0x3A50, 0x3E16, 0x41E2, 0x45B3, 0x498B, 0x4D67, 0x5549, 0x592E, 0x6117, 0x6903, 0x6CF2, 0x74E2, 0x7CD4, 0x84C8, 0x88BD, 0x90B3, 0x98AA, 0xA0A1, 0xA89A, },
{0x42CF, 0x4296, 0x425F, 0x462B, 0x45FB, 0x49CF, 0x51A9, 0x5586, 0x5967, 0x614D, 0x6535, 0x6D20, 0x710D, 0x78FC, 0x80ED, 0x88E0, 0x8CD4, 0x94C9, 0x9CBF, 0xA4B6, 0xACAE, },
{0x4ACF, 0x4A9D, 0x4A6B, 0x4A3C, 0x4E10, 0x51E7, 0x55C2, 0x59A1, 0x6182, 0x6567, 0x694F, 0x713A, 0x7926, 0x7D15, 0x8505, 0x88F7, 0x90EA, 0x98DF, 0xA0D4, 0xA8CA, 0xACC1, },
{0x52CF, 0x52A2, 0x5275, 0x524A, 0x5621, 0x59FB, 0x5DD8, 0x61B8, 0x659A, 0x6980, 0x7167, 0x7552, 0x7D3E, 0x812C, 0x891C, 0x910D, 0x9500, 0x9CF3, 0xA4E8, 0xA8DE, 0xB0D4, },
{0x5ACF, 0x5AA6, 0x5A7D, 0x5A55, 0x5E30, 0x620C, 0x65EB, 0x69CC, 0x6DAF, 0x7195, 0x757D, 0x7D67, 0x8154, 0x8941, 0x8D31, 0x9522, 0x9914, 0xA107, 0xA8FB, 0xACF0, 0xB4E6, },
{0x62CF, 0x62A9, 0x6284, 0x625F, 0x663C, 0x6A1B, 0x69FB, 0x6DDD, 0x71C2, 0x79A9, 0x7D91, 0x817B, 0x8567, 0x8D55, 0x9144, 0x9935, 0xA126, 0xA519, 0xAD0D, 0xB102, 0xB8F7, },
{0x6ACF, 0x6AAC, 0x6A8A, 0x6A68, 0x6E47, 0x6E27, 0x7209, 0x75ED, 0x79D3, 0x7DBA, 0x81A3, 0x898E, 0x8D7A, 0x9167, 0x9957, 0x9D47, 0xA538, 0xA92B, 0xB11E, 0xB913, 0xBD08, },
{0x72CF, 0x72AF, 0x728E, 0x726F, 0x7650, 0x7632, 0x7A16, 0x7DFB, 0x81E2, 0x85CA, 0x89B3, 0x8D9E, 0x918B, 0x9978, 0x9D67, 0xA558, 0xA949, 0xB13B, 0xB52E, 0xBD23, 0xC117, },
{0x7ACF, 0x7AB1, 0x7A93, 0x7A75, 0x7E58, 0x7E3C, 0x8221, 0x8607, 0x89EF, 0x89D8, 0x91C2, 0x95AD, 0x999A, 0x9D88, 0xA577, 0xA967, 0xAD59, 0xB54B, 0xB93E, 0xC132, 0xC926, },
{0x82CF, 0x82B3, 0x8296, 0x827B, 0x825F, 0x8645, 0x8A2B, 0x8A12, 0x8DFB, 0x91E5, 0x95CF, 0x99BB, 0xA1A9, 0xA597, 0xA986, 0xAD76, 0xB567, 0xB95A, 0xC14D, 0xC540, 0xCD35, },
{0x8ACF, 0x8AB5, 0x8A9A, 0x8A7F, 0x8A66, 0x8E4C, 0x9234, 0x921C, 0x9606, 0x99F0, 0x9DDC, 0xA1C8, 0xA5B6, 0xA9A4, 0xB194, 0xB584, 0xB975, 0xC167, 0xC55A, 0xC94E, 0xD142, },
{0x92CF, 0x92B6, 0x929D, 0x9284, 0x926B, 0x9653, 0x963C, 0x9A25, 0x9E10, 0xA1FB, 0xA5E7, 0xA9D4, 0xADC2, 0xB1B1, 0xB5A1, 0xB991, 0xC182, 0xC575, 0xC967, 0xD15B, 0xD54F, },
{0x9ACF, 0x9AB7, 0x9A9F, 0x9A88, 0x9A70, 0x9E5A, 0x9E43, 0xA22E, 0xA619, 0xAA05, 0xA9F1, 0xADDF, 0xB1CD, 0xB9BC, 0xBDAC, 0xC19D, 0xC58F, 0xC981, 0xD174, 0xD567, 0xDD5C, },
{0xA2CF, 0xA2B9, 0xA2A2, 0xA28B, 0xA275, 0xA65F, 0xA64A, 0xAA35, 0xAE21, 0xAE0E, 0xB1FB, 0xB5E9, 0xB9D8, 0xBDC7, 0xC1B8, 0xC9A9, 0xCD9A, 0xD18D, 0xD580, 0xDD73, 0xE167, },
};

// 此处通过 uint32_t 返回数据由于数据丢失会产生奇特的效果
static uint16_t _kbRGB_Angle(float x, float y, float cx, float cy)
{
    double angle    = (atan2(x - cx, y - cy)) * 180 / 3.14159265359;
    double distance = sqrt(pow(cx - x, 2) + pow(cy - y, 2));

    struct kbRGB_PixelLimit piont;
#if 0
    piont.angle = (uint16_t)(angle*8.0f);     // 90*8 = 720:10bit[1024]
    piont.radius = (uint16_t)(distance);
    piont.radius = (uint16_t)(distance*2.0); // sqrt(21*21)*2 = 29.7*2 = 60: 6bit [64]
#else
    const float kbRGB_angls_pre = (float)(0x1<<KBRGB_ANGLE_PRE);
    const float kbRGB_radius_pre = (float)(0x1<<KBRGB_RADIUS_PRE);
    piont.angle = (uint16_t)(angle*kbRGB_angls_pre);     // 90*8 = 720:10bit[1024]
    piont.radius = (uint16_t)(distance*kbRGB_radius_pre); // sqrt(21*21)*2 = 29.7*2 = 60: 6bit [64]
#endif
    return piont.pixel;
}
/*************************************************************************************************
* 为节省空间占用,仅计算 0-90°范围,其它角度根据象限间的关系重新计算
* 为节保留 精度并加快运算速度,将处理后的结果保存为整型，精度为 1/64
**************************************************************************************************/
void kbRGB_Angle(const uint16_t cols, const uint16_t rows)
{
    float cx = 0;//(cols - 1) * 0.5;
    float cy = 0;//(rows - 1) * 0.5;
    struct kbRGB_PixelLimit matrix[128][128];
    for (uint32_t col_id = 0; col_id < cols; col_id++)
    {
        for (uint32_t row_id = 0; row_id < rows; row_id++)
        {
            matrix[col_id][row_id].pixel = _kbRGB_Angle(col_id, row_id, cx, cy);
        }
    }
    //printf("const uint16_t RotateMatrix[%d][%d] = {\r\n", MATRIX_SIZE, MATRIX_SIZE);
    //printf("const uint16_t RotateMatrixAngle[MATRIX_SIZE][MATRIX_SIZE] = {\r\n");
    //printf("const uint32_t RotateMatrixAngle[%d][%d] = {\r\n", cols, rows);
    printf("static const uint16_t RotateMatrixAngle[KBRGB_ANGLE_SIZE][KBRGB_ANGLE_SIZE] = {\r\n");
    for(int y=0; y<rows; y++)
    {
        printf("{");
        for(int x=0; x<cols; x++)
        {
            //printf("%4d, ",  (int)matrix[y][x].angle);
            printf("0x%04X, ",  matrix[y][x].pixel);
        }
        printf("},\r\n");
    }
    printf("};\r\n");
#if 0
    printf("static const uint16_t angle[MATRIX_ANGLE_SIZE][MATRIX_ANGLE_SIZE] = {\r\n");
    for(int y=0; y<rows; y++)
    {
        printf("{");
        for(int x=0; x<cols; x++)
        {
            //printf("%4d, ",  (int)matrix[y][x].angle);
            printf("%3d, ",  matrix[y][x].angle);
        }
        printf("},\r\n");
    }
    printf("};\r\n");
    printf("static const uint16_t radius[MATRIX_ANGLE_SIZE][MATRIX_ANGLE_SIZE] = {\r\n");
    for(int y=0; y<rows; y++)
    {
        printf("{");
        for(int x=0; x<cols; x++)
        {
            //printf("%4d, ",  (int)matrix[y][x].angle);
            printf("%3d, ",  matrix[y][x].radius);
        }
        printf("},\r\n");
    }
    printf("};\r\n");
#endif
    fflush(stdout);
}
void kbRGB_Angle2(void)
{
    kbRGB_Angle(KBRGB_ANGLE_SIZE, KBRGB_ANGLE_SIZE);
}
uint32_t kbRGB_AngleGet(const int16_t x, const int16_t y)
{
    struct kbRGB_PixelLimit Piont = {0};
    struct kbRGB_Pixel piont = {.angle=0, .radius=0xFFFF};
    if((x>=KBRGB_ANGLE_SIZE) || (x<=-KBRGB_ANGLE_SIZE)) return piont.pixel;
    if((y>=KBRGB_ANGLE_SIZE) || (y<=-KBRGB_ANGLE_SIZE)) return piont.pixel;
    if((x>=0) && (y>=0)) // 第一象限
    {
        Piont.pixel = RotateMatrixAngle[y][x];
        piont.angle = Piont.angle;
        piont.radius = Piont.radius;
    }
    if((x<0) && (y>=0)) // 第二象限
    {
        Piont.pixel = RotateMatrixAngle[y][-x];
        piont.angle = Piont.angle;
        piont.radius = Piont.radius;
        //piont.angle = (uint32_t)(180*8) - piont.angle;
        piont.angle = ((uint32_t)180<<KBRGB_ANGLE_PRE) - piont.angle;
    }
    if((x<0) && (y<0)) // 第三象限
    {
        Piont.pixel = RotateMatrixAngle[-y][-x];
        piont.angle = Piont.angle;
        piont.radius = Piont.radius;
        //piont.angle = (uint32_t)(180*8) + piont.angle;
        piont.angle = ((uint32_t)180<<KBRGB_ANGLE_PRE) + piont.angle;
    }
    if((x>=0) && (y<0)) // 第四象限
    {
        Piont.pixel = RotateMatrixAngle[-y][x];
        piont.angle = Piont.angle;
        piont.radius = Piont.radius;
        //piont.angle = (uint32_t)(360*8) - piont.angle;
        piont.angle = ((uint32_t)360<<KBRGB_ANGLE_PRE) - piont.angle;
    }
    return piont.pixel;
}
